Verilog-A 常用器件模型(模板)

可直接复用的行为模型模板,基于吴顺珉书与 Cadence ahdl 库整理。

1. 电阻

`include "constants.vams"
`include "disciplines.vams"
module my_resistor(p, n);
inout p, n;
electrical p, n;
parameter real r = 100;          // 阻值 (Ohm)
analog begin
    V(p, n) <+ r * I(p, n);
end
endmodule

2. 电容 / 电感

// 电容:I = C·dV/dt
module my_capacitor(p, n);
inout p, n;
electrical p, n;
parameter real c = 1p;
analog begin
    I(p, n) <+ c * ddt(V(p, n));
end
endmodule

// 电感:V = L·dI/dt
module my_inductor(p, n);
inout p, n;
electrical p, n;
parameter real l = 1n;
analog begin
    V(p, n) <+ l * ddt(I(p, n));
end
endmodule

3. RLC 串联(组合阻抗示例)

module series_rlc1 (p, n);
parameter real r = 100;
parameter real l = 1n;
parameter real c = 1p exclude 0;   // 防止 c=0
inout p, n;
electrical p, n;
analog begin
    V(p,n) <+ r*I(p,n);
    V(p,n) <+ l*ddt(I(p,n));
    V(p,n) <+ idt(I(p,n))/c;
end
endmodule

4. 电压放大器(V→V)

module amp(inp, inn, outp, outn);
input inp, inn;
output outp, outn;
electrical inp, inn, outp, outn;
parameter real gain = 10;
parameter real rin = 1M;          // 输入阻抗
parameter real rout = 1K;         // 输出阻抗
analog begin
    // 输入阻抗
    I(inp) <+ V(inp)/rin;
    I(inn) <+ V(inn)/rin;
    // 增益 + 输出阻抗
    V(outp, outn) <+ gain*V(inp, inn) + rout*I(outp, outn);
end
endmodule

5. 比较器(tanh 限幅,Cadence ahdl 风格)

module comparator(sigin, sigref, sigout);
input sigin, sigref;
output sigout;
electrical sigin, sigref, sigout;
parameter real sigout_high = 10;
parameter real sigout_low  = -10;
parameter real sigin_offset = 0;
parameter real comp_slope = 1000;

analog begin
    @(initial_step) begin
        if (sigout_high <= sigout_low) begin
            $display("Range specification error: sigout_high=%E <= sigout_low=%E", sigout_high, sigout_low);
            $finish;
        end
    end
    V(sigout) <+ 0.5*(sigout_high - sigout_low)
                * tanh(comp_slope*(V(sigin, sigref) - sigin_offset))
                + (sigout_high + sigout_low)/2;
end
endmodule

加磁滞(hysteresis)版本:

real real_offset;
analog begin
    real_offset = sigin_offset + (V(sigout) > (sigout_high+sigout_low)/2 ? 1e-3 : -1e-3);
    V(sigout) <+ 0.5*(sigout_high - sigout_low)
                * tanh(comp_slope*(V(sigin, sigref) - real_offset))
                + (sigout_high + sigout_low)/2;
end

6. 带磁滞 + 摆率限制的比较器(Model Writer 风格)

module compt_test4 (vin_p, vin_n, vout);
input vin_p, vin_n;
output vout;
electrical vin_p, vin_n, vout;
parameter real hys = 2m from (0:inf);
parameter real p_off = 10.0u;
parameter real n_off = -10.0u;
parameter real slope = 1000.0 from (0:inf);
parameter real one = 5.0;
parameter real zero = 0.0;
parameter real slewp = 10.0M from (0:inf);
parameter real slewn = -10.0M from (-inf:0);
parameter integer traceflag = 0;

real vin, mag, offset, halfhys, outv;
analog begin
    @(initial_step("ac","dc","tran","xf")) begin
        halfhys = hys/2.0;
        mag = (one - zero)/2.0;
        offset = (one + zero)/2.0;
        if (traceflag)
            $strobe("%M Initialization: vout: %g hys/2:%g", V(vout), halfhys);
    end
    vin = V(vin_p) + p_off - V(vin_n) + n_off;
    @(cross(vin - hys, +1)) begin
        halfhys = hys/2.0;
        if (traceflag) $strobe("%M at %g sec. output going high", $abstime);
    end
    @(cross(vin + hys, -1)) begin
        halfhys = -hys/2.0;
        if (traceflag) $strobe("%M at %g sec. output going low", $abstime);
    end
    outv = mag*tanh(slope*(vin - halfhys)) + offset;
    V(vout) <+ slew(outv, slewp, slewn);
end
endmodule

tanh 保证 DC 连续无突变;slew 保证瞬态有限摆率。

7. 二极管(limexp + limit)

module diode(a, c);
inout a, c;
electrical a, c;
parameter real IS = 1.0e-14;
parameter real CJO = 0.0;

analog function real spicepnjlim;
    input vnew, vold, vt, vcrit;
    real vnew, vold, vt, vcrit, vlimit, arg;
    begin
        vlimit = vnew;
        if ((vnew > vcrit) && (abs(vnew-vold) > (vt+vt))) begin
            if (vold > 0) begin
                arg = 1 + (vnew-vold)/vt;
                if (arg > 0) vlimit = vold + vt*ln(arg);
                else vlimit = vcrit;
            end else
                vlimit = vt*ln(vnew/vt);
            $discontinuity(-1);
        end
        spicepnjlim = vlimit;
    end
endfunction

real vdio, idio, qdio, vcrit;
analog begin
    vcrit = 0.7;
    vdio = $limit(V(a,c), spicepnjlim, $vt, vcrit);
    idio = IS * (exp(vdio/$vt) - 1);
    I(a,c) <+ idio;
    if (vdio < 0.5)
        qdio = 0.5*CJO*(1-sqrt(1-V(a,c)));
    else
        qdio = CJO*(2.0*(1.0-sqrt(0.5)) + sqrt(2.0)/2.0*(vdio*vdio+vdio-3.0/4.0));
    I(a,c) <+ ddt(qdio);
end
endmodule

8. 8bit ADC(事件 + genvar 循环)

module adc(out, in, clk);
parameter real fullscale = 1.0;
parameter real td = 0, tt = 0;
parameter real vdd = 5.0;
parameter real thresh = vdd/2;
input in, clk;
output [0:7] out;
voltage in, clk;
voltage [0:7] out;
real sample, midpoint;
integer result[0:7];
integer i;
genvar j;

analog begin
    @(cross(V(clk)-thresh, 1) or initial_step) begin
        sample = V(in);
        midpoint = fullscale/2.0;
        for (i = 7; i >= 0; i = i - 1) begin
            if (sample > midpoint) begin
                result[i] = 1;
                sample = sample - midpoint;
            end else result[i] = 0;
            sample = 2.0*sample;
        end
    end
    for(j=0;j<8;j=j+1)
        V(out[j]) <+ transition(result[j] ? vdd : 0.0, td, tt);
end
endmodule

9. 随机噪声源(Vos 随机失调,MC 可用)

module random(out, gnd);
output out;
electrical out;
inout gnd;
electrical gnd;
integer seed;
real vos_number;

analog begin
    @(initial_step) begin
        seed = 123;   // 固定种子:每次仿真相同
        // seed = $cds_get_mc_trial_number();  // MC 模式每试次不同
    end
    @(timer(0, 10u))
        vos_number = rdist_normal(seed, 0, 1);
    V(out, gnd) <+ vos_number;
end
endmodule

10. 滤波器:S 域(laplace)与瞬态等效

// S 域版:H(s) = 3.948e15 / (s² + 8.886e7·s + 3.948e15)
module filter2(in, out, gnd);
input in; electrical in;
output out; electrical out;
inout gnd; electrical gnd;
analog begin
    V(out, gnd) <+ laplace_nd(V(in, gnd), {3.948e15,0,0}, {3.948e15,8.886e7,1});
end
endmodule

// Z 域版:理想积分器(采样保持)
module filterz(in, out, gnd);
input in; electrical in;
output out; electrical out;
inout gnd; electrical gnd;
analog begin
    V(out, gnd) <+ zi_nd(V(in, gnd), {0,1}, {1,-1}, 50u);
end
endmodule

建模要点回顾

  1. 先算数值再赋值输出(减少模拟量相互影响)。
  2. 参数化 + exclude 0 防除零。
  3. tanh 限幅、slew/transition 加非理想。
  4. traceflag/DEBUG 参数 开关调试输出。
  5. initial_step 中做参数校验(如 sigout_high <= sigout_low 报错退出)。

相关笔记